// 设备播放树
<template>
  <div class="addr-container">
    <el-input placeholder="请输入搜索内容" v-model="left_addr" class="search">
      <i slot="prefix" class="el-input__icon el-icon-search"></i>
    </el-input>

    <el-select clearable v-model="check_group" placeholder="选择公司" @change="handleGroup" class="group-select">
      <el-option v-for="item in list_group" :key="item.id" :label="item.label" :value="item.id"></el-option>
    </el-select>

    <el-cascader clearable class="addr-select" placeholder="选择省市区.街道" :options="list_province" :props="the_props" @change="handleNode" filterable></el-cascader>

    <!-- 网点列表 -->
    <div class="device-tree-container" v-loading="tree_loading">
      <div class="scroll-content" v-if="!tree_loading && list_branch.length > 0">
        <el-tree ref="device_tree" class="device-tree" :props="defaultProps" lazy :load="loadNode" node-key="id"
                highlight-current :data="list_branch" empty-text="未查询到数据" @node-click="clickNode">

          <div slot-scope="{ node, data }">
            <!-- (1) 直播视频 -->
            <span v-if="model==0" class="custom-tree-node" :class="online_Status(data, node)? 'node-text':'device__disabled'" :title="online_Status(data, node)?'':'离线'" >
              <!-- 网关icon -->
              <i v-if="node.level==1" :class="online_Status(data, node)? 'iconfont icon-ditu10 icon-left':'iconfont icon-ditu10 icon-color'"></i>
              <i v-else-if="node.level==2" :class="online_Status(data, node)? 'iconfont icon-host icon-left':'iconfont icon-host icon-color'"></i>
              <!-- 设备icon "摄像头" -->
              <template v-else>
                <i v-if="!node.data.collect_inline" class="el-icon-star-off" @click="collectOff(node)"></i>
                <i v-if="node.data.collect_inline" class="el-icon-star-on"  @click="collectOn(node)"></i>
                <!-- <i :class="iconDevice(node.data.status, node.data.type)" class="iconfont icon-shipin2"></i> -->
                <!-- <i v-if="node.checked" class="iconfont icon-shipin8 play-video"></i> -->
              </template>
              <span>{{ node.label }}</span>
              <!-- <el-tooltip content="没有绑定存储模板!" placement="top">
                <div v-if="node.data.deviceId && node.data.recordTemplateId==null" class="point-red"></div>
              </el-tooltip> -->
            </span>

            <!-- (2) 历史回放视频 -->
            <span v-else-if="model==1" class="custom-tree-node node-text" >
              <i v-if="!node.data.deviceId" class="iconfont icon-ditu10"></i>
              <template v-else>
                <i :class="iconDevice(node.data.status, node.data.type)" class="iconfont icon-shipin"></i>
                <i v-if="node.checked" class="play-video"></i>
              </template>
              <span>{{ node.label }}</span>
              <el-tooltip content="没有绑定存储模板!" placement="top">
                <div v-if="node.data.deviceId && node.data.recordTemplateId==null" class="point-red"></div>
              </el-tooltip>
            </span>
          </div>

        </el-tree>
      </div>
      <Empty v-else-if="!tree_loading && list_branch.length == 0"/>
    </div>

  </div>
</template>

<script>
import waves from "@/directive/waves"; // waves directive
import { parseTime } from "@/utils"; // 解析时间
import { getProvinces, getCity, getArea, getStreet, getUserAddress, } from "@/api/address";
import { branchList, deviceList } from "@/api/branch";
import Empty from "@/components/Empty/index.vue";
import "jquery.nicescroll";

const calendarTypeOptions = [
  { key: "CN", display_name: "China" },
  { key: "US", display_name: "USA" },
  { key: "JP", display_name: "Japan" },
  { key: "EU", display_name: "Eurozone" },
];

// arr to obj, such as { CN : "China", US : "USA" }
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
  acc[cur.key] = cur.display_name;
  return acc;
}, {});

export default {
  name: "DeviceTree",
  components: { Empty },
  props: {
    grid_len: {   // 宫格数量, 可播放视频数量的上限
      type: [String, Number],
      default: 1,
    },
    model: {   // 0直播视频,  1历史视频, 2下载中心
      type: [String, Number],
      default: 0,
    },
    grid_select: {   // 当前被选择中的 宫格位置序号
      type: [String, Number],
      default: -1,
    }
  },

  directives: { waves },
  filters: {
    statusFilter(status) {
      const statusMap = {
        published: "success",
        draft: "info",
        deleted: "danger",
      };
      return statusMap[status];
    },
    typeFilter(type) {
      return calendarTypeKeyValue[type];
    },
  },
  data() {
    const validatePassword = (rule, value, callback) => {
      // if (!validPass(value) && (value && value.length != 64)) {
      if (!validPass(value)) {
        callback(new Error("8~16位,包含大小写字母和数字, 可以有特殊字符"));
      } else {
        callback();
      }
    };

    return {
      // 节流
      current: true,
      // 左侧 tree 区
      left_addr: "", // 左侧地址搜索

      list_province: [],   // 省列表
      cut_node: "", // 当前省\市\区 的节点code
      cut_level: "", // 当前节点的等级
      check_group: '', // 已选的公司
      cut_branch: {
        id: '',
        name: ''
      },
      cut_branch2: {
        id: '',
        name: '',
      },
      cut_device: '',   // 当前的设备id
      list_group: [
        { id: '', label: "全部" },
        { id: 11, label: "邮政" },
        { id: 12, label: "圆通" },
        { id: 13, label: "申通" },
        { id: 14, label: "中通" },
        { id: 15, label: "韵达" },
        { id: 16, label: "顺丰" },
      ],
      list_branch: [],   // 网点列表
      tree_loading: true,   // 网点播放数据正在加载中
      list_device: [],   // 设备列表


      defaultProps: {
        // children: 'channels',
        // label: 'name',
        label: (data, node) => {
          if (node.level === 1) {
            // 第一层lable为name字段
            return data.name;
          } 
          else if (node.level === 2 || node.level === 3) {
            // 第二三层lable为name字段
            return data.name;
          }
        },
        isLeaf: (data, node) => {
          if (node.level === 3) {
            // 第三层没有子节点
            return true;
          }
        },
      },

      checkedNodes: new Array(1), // 选中的node集合 ###
      replaceNum: 0, // 替换的视频 宫格位置号 ###

      the_props: {
        // 级联选择器的 配置
        checkStrictly: true, // 父子节点不相互关联
        lazy: true,
        lazyLoad(node, resolve) {
          const { level } = node;
          if (node.level == 1)
            getCity({ provinceCode: node.value }).then((res) => {
              const list = res.data.map((item, i) => {
                item.value = item.cityCode;
                item.label = item.cityName;
                return item;
              });
              resolve(list);
            });
          else if (node.level == 2)
            getArea({ cityCode: node.value }).then((res) => {
              const list = res.data.map((item, i) => {
                item.value = item.areaCode;
                item.label = item.areaName;
                return item;
              });
              resolve(list);
            });
          else if (node.level == 3)
            getStreet({ areaCode: node.value }).then((res) => {
              const list = res.data.map((item, i) => {
                item.value = item.streetCode;
                item.label = item.streetName;
                return item;
              });
              resolve(list);
            });
          else if (node.level == 4) {
            // this.cut_node = node.value
            // this.cut_level = node.level
            resolve()
          }
        },
      },
      
    };
  },
  watch: {
    left_addr(nel, old) {
      if (nel == '') {
        this.getBranchList()
      } else if (this.current) {
        this.current = false
        this.getBranchList()
        setTimeout(() => {
          this.current = true
        },300);
      }
    },
    grid_len(newVal, oldVal) {   // 监听宫格数量的变化 1, 4, 9, 12, 16, 24
      let remindval = newVal < oldVal ? newVal : oldVal; // 所要保留视频数量的上限
      let resultArr = [];
      if (this.grid_select !== -1) {   // 当前有被选中的宫格
        resultArr.push( this.checkedNodes[this.grid_select] )
        remindval = remindval - 1;
      }

      if(newVal > oldVal){   // 如果宫格数变大
        for (let i = 0; i < oldVal; i++) {
          if ( this.checkedNodes[i] && this.checkedNodes[i].checked && i !== this.grid_select) {
            resultArr.push(this.checkedNodes[i])
          }
        }
      }
      else {   // 宫格数变小
        let count = 0
        for (let i = 0; i < oldVal; i++) {
          if( this.checkedNodes[i] && this.checkedNodes[i].checked && i != this.grid_select && count < remindval) {
            resultArr.push(this.checkedNodes[i])
            count++
          }
          else if( this.checkedNodes[i] && this.checkedNodes[i].checked && i !== this.grid_select) {
            this.checkedNodes[i].checked = false;   // 关闭其余视频??? ###
          }
        }
      }
      
      this.checkedNodes = new Array(newVal)   // 根据宫格数, 更改数组长度

      this.replaceNum = 0;
      // this.grid_select = -1;
      this.$parent.changeGridSelect()

      for (let i = 0; i < resultArr.length; i++) {
        // this.checkedNodes[i] = resultArr[i];
        this.$set(this.checkedNodes, i, resultArr[i])
        
        if (resultArr[i]) {
          this.$emit("node-click", resultArr[i].data, resultArr[i].checked, i, resultArr[i]);   // 打开视频 ??? ###
        }
        // else {
        //   this.$emit('node-click', null, false, i)
        // }
      }
    },

  },
  created() {
    this.getProvinces();
  },
  mounted() {
    // let addr_code = this.$store.getters.addr_code
    // let user_level = this.$store.getters.level
    // if(addr_code) this.handleNode(addr_code.splice(0, user_level))

    // this.handleNode(["110000"]);   // 默认访问北京这个区域
    // this.handleGroup(11);   // 默认访问邮政这个公司
    this.getBranchList()   // 网点列表
  },
  computed: {
    // group_name() {
    //   return (groupId) => {
    //     if (groupId == 11) return "邮政";
    //     else if (groupId == 12) return "圆通";
    //     else if (groupId == 13) return "申通";
    //     else if (groupId == 14) return "中通";
    //     else if (groupId == 15) return "韵达";
    //     else if (groupId == 16) return "顺丰";
    //   };
    // },
    
    iconDevice() {   // 摄像头icon
      return (online) => {
        let result = ''
        if (!online) {
          result += " icon-shipin__disabled";
        }
        return result;
      };
    },
    online_Status() {
      return (data, node) => {
        // if((data.isOnline==1||data.online==1) || (node.parent.data.type==2  && node.parent.data.isOnline == 1)) return true
        if(data.isOnline==1||data.online==1|| node.level==1) return true
        else return false
      }
      
    }

  },
  methods: {
    // 没选中
    collectOff(row) {
      row.data.collect_inline = true
      this.$parent.favoriteList(row.data, row.parent.data.id, row)
    },
    // 选中
    collectOn(row) {
      row.data.collect_inline = false
      this.$parent.favoriteList(row.data)
    },
    // 切换地点
    handleNode(newval) {
      this.cut_level = newval.length || 0
      if(newval) this.cut_node = newval[newval.length - 1]
      this.getBranchList()
      this.$emit("changenode", newval)
    },

    // 切换公司
    handleGroup(val) {
      this.getBranchList()
      this.$emit("changegroup", val)
    },
    // 获取所有省份
    getProvinces() {
      getProvinces().then((res) => {
        this.list_province = res.data || []
        this.list_province = this.list_province.map((item, i) => {
          item.value = item.provinceCode;
          item.label = item.provinceName;
          return item;
        })
      });
    },


    // 获取网点列表=========================================
    getBranchList() {
      let temp_query = { groupId: this.check_group, keyword: this.left_addr };
      // if(this.cut_level == 0) 
      if (this.cut_level == 1) temp_query.provinceCode = this.cut_node;
      else if (this.cut_level == 2) temp_query.cityCode = this.cut_node;
      else if (this.cut_level == 3) temp_query.areaCode = this.cut_node;
      else if (this.cut_level == 4) temp_query.streetCode = this.cut_node;

      branchList(temp_query).then((res) => {
        this.tree_loading = false
        this.list_branch = res.data || [];
      }).catch( (res) => {
        this.tree_loading = false
        this.list_branch = []
        this.$message({
          message: res.msg,
          type: 'error'
        })
      })
    },
    // 加载子节点数据的钩子，当且仅当 lazy == true 时生效
    loadNode(node, resolve) {
      if(node.level==0) {
        return resolve(this.list_branch)
      }
      else if(node.level == 1) {   // 获取某个网点的所有设备
        this.cut_branch2.id = node.data.id
        // this.cut_branch2.id = node.data.id

        // 动态请求该网点的 设备数据
        deviceList({ siteId: this.cut_branch2.id }).then((res) => {
          if(res.code == 0) {
            if (!res.data) {
              return resolve([])
            }
            else {
              this.list_device = res.data.list || []

              this.list_device.forEach((item1) => {
                if (!item1.channels) {
                  // 为空
                } else {
                  item1.channels.forEach((item2) => {
                    this.$set(item2, "collect_inline", false);
                  })
                }
              })
              return resolve(this.list_device)
            }
          }
        }).catch((res) => {
          this.$message({
            message: '该网点下无设备',
            type: 'error'
          })
        })
      }
      else if(node.level == 2) {   // 获取某个nvr设备的所有通道
        return resolve(node.data.channels)
      }
      else if(node.level > 2) {
        return resolve([])
      }
    },

    // 点击某个设备 -------------------------------------------------------------------------------
    clickNode(data, node, page) {
      // console.log(node)
      this.cut_device = data.id
      // 与历史页面 切换时  展开当前页面
      // let select_arr = []
      // function addParent(node) {   // 获取当前节点的父节点(解决不同页面切换时, 聚焦当前节点的问题)
      //   if(node && node.parent && typeof(node.parent.key)!= 'undefined' && node.parent.key != null) {
      //     select_arr.push(node.parent.key)
      //     addParent(node.parent)
      //   }
      // }
      // addParent(node)
      // if(node.expand) {select_arr.push(node.key)}   // 根据展开与否

      // if(node.level == 3) {   // 点击的是设备, 存上当前节点
      //   this.$store.commit("SAVE_DATA", node)
      // }
      // this.$store.commit("SET_NODE", select_arr)

      // 如下三个变量,页面 暂时未用到
      // this.currLevel = node.level
      // if (node.level === 1) this.currSignal = node.data;   // level == 1
      // if (node.level === 2) this.currChannel = node.data;   // level == 2

      if(node.level==1 || node.level==2) return
      else if(node.level==3){
        // model==1历史模式----------------------------------------
        if(this.model==1) {
          if (data && data.deviceId && data.status !== 0) {   // 有设备id 并且状态值不为 0   (可以将data.deviceId 换成 node.level)
            if( data.checked && page != 'change') {   // 被点击的摄像头 正在播放,  则去关闭视频
              this.toggleVideo(0, data, false)   // 关闭当前视频
            }
            else{
              if(this.checkedNodes[0] && page != 'change') {
                this.toggleVideo(0, this.checkedNodes[0], false)   // 关闭原来视频
              }
              this.toggleVideo(0, data, true)   // 打开当前视频
            }
          }
        }
        // model==0 直播-----------------------------------------------------
        else if(this.model==0) {
          if( node.parent.data.online == 1 && data.online ==1 ) {   // 以下是在线视频, 直播状态被点击
            if(node.checked) {   // 被点击的摄像头 正在播放,  则去关闭视频
              console.log('被点击的摄像头, 正在播放');
              const position = this.getNodePositionByKey(data.id);   // 通过摄像头id 获取到播放该视频的 宫格位置号
              this.toggleVideo(position, node, data, false)   // 关闭当前视频
              // this.toggleVideo(position, undefined, this.checkedNodes[position].data, false)
            }
            else if (this.grid_select === -1) {   // 未处于播放状态,并且无活跃宫格, 找一个位置去播放视频
              console.log('被点击的摄像头, 未处于播放状态, 无活跃宫格')
              const position = this.getInsertPosition();

              this.toggleVideo(position, node, data, true)   // 打开当前视频
            }
            else {   // 未处于播放状态, 在活跃的宫格中 打开视频
              console.log('被点击的摄像头, 未处于播放播放, 有活跃宫格')
              if(this.checkedNodes[this.grid_select] != undefined) {   // 活跃的宫格里边有视频, 先关闭原来的
                this.toggleVideo(this.grid_select, this.checkedNodes[this.grid_select], this.checkedNodes[this.grid_select].data, false)   // 关闭原来视频
              }
              this.toggleVideo(this.grid_select, node, data, true)   // 打开视频
            }
          }
          else {
            this.$message({
              message: "设备不在线",
              type: "warning",
              duration: 4000,
            })
          }
        }
      }
    },

    // 获得一个宫格位置, 用来播放摄像头
    getInsertPosition() {
      let position = -1;
      for (let i = 0; i < this.grid_len; i++) {
        // 如果有空位置，返回第一个空位置作为插入点
        if (position === -1 && this.checkedNodes[i] == undefined) {
          position = i;
          break;
        }
      }
      if (position === -1) {   // 没有空位置了，按照replaceNum替换视频
        position = this.replaceNum % this.grid_len;
        this.replaceNum++;
        // 需要将替换  让原来的视频取消播放
        this.toggleVideo(position, this.checkedNodes[position], this.checkedNodes[position].data, false)   // 关闭原来视频
      }
      return position;
    },
    // 通过摄像头id 获到播放该视频的宫格位置号
    getNodePositionByKey(key) {
      let position = -1;
      for (let i = 0; i < this.grid_len; i++) {
        if (this.checkedNodes[i] && this.checkedNodes[i].data.id === key) {
          position = i;
          break;
        }
      }
      return position;
    },
    // 父组件通过ref 调用该函数 关闭视频
    closeVideo(position) {
      this.toggleVideo(position, this.checkedNodes[position], this.checkedNodes[position].data, false)
    },
    // 关闭\打开 视频
    toggleVideo(position, node, data, toggle) {
      this.$emit("node-click", data, toggle, position, node);
      node.checked = toggle
      if(toggle) this.$set(this.checkedNodes, position, node)
      else { this.$set(this.checkedNodes, position, undefined) }   // ### 关闭视频
    },

    // 过滤: 当前的节点是否显示出来
    filterNode(value, data) {
      if (!value) return true;   // 没有索引关键字, 则所有节点都显示
      return data.name.indexOf(value) !== -1;   // 有索引关键字,则带关键字的才显示
    },
    // 父组件点击搜索, 会通过ref调用这个函数
    searchTree(val) {   // backview.vue文件  通过ref调用了这个函数
      this.$refs.qnTree.filter(val);   //filter是el-tree自带的方法 接收一个任意类型的参数，该参数会在 filter-node-method 中作为第一个参数
    },
  },
};
</script>

<style lang="scss">
  @import "~@/styles/variables.scss";
.device-tree-container{
  .el-tree-node {
    width: 100% !important;
    &.is-expanded {
      .el-tree-node__expand-icon {
        color: $my-primary;
      }
      .custom-tree-node {
        .icon-left {
          color: $my-primary;
        }
        .icon-color {
          color: #bbbbbb;
          cursor: default;
        }
        .pNode {
          color: $my-primary;
        }
      }
    }
  }
  .el-tree-node__content {
    width: 100%;
    padding-right: 10px;
  }
  .el-tree-node__expand-icon {
    font-family: "iconfont" !important;
    font-size: 12px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    &.el-icon-caret-right:before {
      content: "\e693";
    }
    &.is-leaf {
      color: transparent !important;
    }
  }
  .el-icon-caret-right {
    color: $text_dark;
    padding-left: 0;
  }
  .custom-tree-node {
    // background-color: aqua;
    .point-red {
      margin-left: 5px;
      width: 6px;
      height: 6px;
      cursor: pointer;
      display: inline-block;
      background-color: #f33;
      border-radius: 50%;
      transform: translateY(-3px);
    }
    position: relative;
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-break: break-all;
    .icon-left {
      color: $text_dark;
      margin-right: 3px;
    }
    .icon-shipin {
      color: $text_dark;
      margin-right: 2px;
    }
    .play-video {
      color: $my-primary;
      font-weight: 700;
      font-size: 12px;
      position: absolute;
      left: 8px;
      top: 6px;
      display: inline-block;
    }
    &.node-text {
      color: $text_dark;
    }
    &.device__disabled {
      cursor: default;
      color: #bbbbbb !important;
      // cursor: not-allowed;
      .icon-shipin__disabled {
        color: rgb(134, 134, 134);
      }
    }
  }
  .notOnline {
    color: gold;
  }
}
</style>


<style lang="scss" scoped>
  @import "~@/styles/variables.scss";

.addr-container {
  background-color: #fff;
  padding: 5px;
  .search {
    margin-bottom: 20px;
  }
  .group-select {
    margin-bottom: 20px;
  }
  .addr-select {
    margin-bottom: 20px;
  }
  
  .device-tree-container {
    height: 100%;
    // background-color: #f99;
    .scroll-content {
      // 不要滚动条了
      // overflow: scroll;
      
      // background-color: #f00;
      .device-tree {
        width: 100%;
        // overflow: scroll;
        // background-color: #aaf;
      }
    }
    
  }
}
</style>
